// Filename:    Login.cpp
// Author:      John Van Drasek
// Date:		3/11/2011
// Description:


// Includes
// User defined includes
#include "Login.h"


// loginToServer
//
//  Description: Login to a NHO server with a username and password.
//
//  Input: char* inServerAddress - Server address to login to
//  Input: char* inUsername - Username for login attempt
//  Input: char* inPassword - Password for login attempt
//  Output: bool result - True represents a successful login and
//           false represents a failed login attempt.
//
bool LoginToServer(char* inServerAddress, char* inUsername, char* inPassword)
{
	// Variable declarations
	int sock, rc, fromlen;
	bool result;
	struct pkt* myPkt;
	struct pkt inPkt;
	struct sockaddr_in client;
	struct sockaddr_in from;
	struct hostent *h;

	// Variable assignments
	result = false;
	fromlen = sizeof(struct sockaddr_in);

	// **Important for Winsock**
	// RUP calls WSAStartup() in the rup_open(), which is required
	// prior to any calls including gethostbyname() which notice is
	// right after this call.
	// Create socket
	sock = rup_open();

	// Assign values to the client sockaddr_in struct
	//   family - INET is tcp/ip/ethernet
	//   addr - IP address of server
	//   port - Port number of server
	h = gethostbyname(inServerAddress);
	if ( h == 0 )
	{
		printf("ERROR(AutoJob::LoginToServer): Cannot find host %s\n",inServerAddress);
		return false;
	}

	memcpy(&client.sin_addr, h->h_addr, h->h_length);
	client.sin_family = AF_INET;

	// convert host short to network byteorder short
	client.sin_port = htons(SERVERLOGINPORT);

	// Create a pkt
	myPkt = createPkt(1,"login",&client,inUsername,inPassword,"",0);

	// Performing the checksum and assigning it to the pkt
	myPkt->_checksum = performChecksum(myPkt);

	// Write login pkt to server
	if(rup_write(sock,myPkt,sizeof(struct pkt),&client) < 0)
	{
		printf("ERROR(AutoJob::LoginToServer): Failed sending datagram to server(errno %d)\n", errno);
		delete myPkt;
		return false;
	}

	// Read result pkt from server
	if ((rc=rup_read(sock, &inPkt, sizeof(struct pkt), &from)) < 0 )
	{
		printf("ERROR(AutoJob::LoginToServer): Failed reading datagram from server(errno %d)\n",errno);
		delete myPkt;
		return false;
	}

	// check to see if return message is success
	if(strcmp(inPkt._msgbuf,"success") == 0)
	{
		// Set return value to true
		result = true;
		strncpy_s(gServerAddress, ADDRESSSIZE, inServerAddress, strlen(inServerAddress));
		strncpy_s(gUsername, NAMESIZE, inUsername, strlen(inUsername));

		// Check to see if return message is failure
	}
	else if(strcmp(inPkt._msgbuf,"failure") == 0)
	{
		// Set return value to false
		printf("ERROR(AutoJob::LoginToServer): Failed to log in to server(errno %d)\n", errno);
		result = false;

		// Return message is not success or failure
	}
	else
	{
		result = false;
	}
	rup_close(sock);
	delete myPkt;

	return result;
}


// logoutoFServer
//
//  Description: Logout of the NHO server.
//
//  Output: bool result - True represents a successful logout and
//           false represents a failed logout attempt.
//
bool LogoutOfServer()
{
	// Variable declarations
	int sock, rc, fromlen;
	bool result;
	struct pkt* myPkt;
	struct pkt inPkt;
	struct sockaddr_in client;
	struct sockaddr_in from;
	struct hostent *h;

	// Variable assignments
	result = false;
	fromlen = sizeof(struct sockaddr_in);

	// Create socket
	sock = rup_open();

	// Assign values to the client sockaddr_in struct
	//   family - INET is tcp/ip/ethernet
	//   addr - IP address of server
	//   port - Port number of server
	h = gethostbyname(gServerAddress);
	if ( h == 0 )
	{
		printf("ERROR(AutoJob::LogoutOfServer): Cannot find host %s\n",gServerAddress);
		return false;
	}

	memcpy(&client.sin_addr, h->h_addr, h->h_length);
	client.sin_family = AF_INET;

	// convert host short to network byteorder short
	client.sin_port = htons(SERVERLOGINPORT);

	// creating a pkt
	myPkt = createPkt(1,"logout",&client,"","","",0);

	// performing the checksum and assigning it to the pkt
	// TODO: perform checksum on a given buffer not just _msgbuf!
	myPkt->_checksum = performChecksum(myPkt);

	// Send login pkt to server
	if(rup_write(sock,myPkt,sizeof(struct pkt),&client) < 0)
	{
		printf("ERROR(AutoJob::LogoutOfServer): Failed sending datagram to server(errno %d)\n", errno);
		delete myPkt;
		return false;
	}

	// Read login result pkt from server
	if ((rc=rup_read(sock, &inPkt, sizeof(struct pkt), &from)) < 0 )
	{
		printf("ERROR(AutoJob::LogoutOfServer): Failed reading datagram from server(errno %d)\n",errno);
		delete myPkt;
		return false;
	}

	// check to see if return message is success
	if(strcmp(inPkt._msgbuf,"success") == 0)
	{
		// set return value to true
		result = true;

		// Check to see if return message is failure
	}
	else if(strcmp(inPkt._msgbuf,"failure") == 0)
	{
		// set return value to false
		printf("ERROR(AutoJob::LogoutOfServer): Failed to log out of server(errno %d)\n", errno);
		result = false;

		// Return message is not success or failure
	}
	else
	{
		result = false;
	}

	rup_close(sock);
	delete myPkt;

	return result;
}
